﻿using System.Drawing;

namespace XYAC.Framework.MonitorTireMaterialOnline.DataExporter
{
    /// <summary>
    /// 表示关键点计算类，用于根据名义值和测量值计算关键点位置。
    /// </summary>
    public class Key
    {
        /// <summary>
        /// 存储计算后的关键点X轴位置的列表。
        /// </summary>
        private List<float> m_KeyX;

        /// <summary>
        /// 存储测量线段的列表。
        /// </summary>
        private List<Line> m_Line;

        /// <summary>
        /// 测量数据实例。
        /// </summary>
        private Measuring m_Measuring;

        /// <summary>
        /// 名义值实例。
        /// </summary>
        private Nominal m_Nominal;

        /// <summary>
        /// 初始化 Key 类的新实例，并计算关键点。
        /// </summary>
        /// <param name="Nominal">名义值实例。</param>
        /// <param name="Measuring">测量值实例。</param>
        public Key(Nominal Nominal, Measuring Measuring)
        {
            if ((Nominal != null) && (Measuring != null))
            {
                this.m_Nominal = Nominal;
                this.m_Measuring = Measuring;

                // 标准点
                PointDataList listSdtKey = this.m_Nominal.ThicknessPoints.SetXOffset(Nominal.XReference);

                // 测量数据
                PointDataList listMeasureData = this.m_Measuring.ThicknessPoints.SetXOffset(Measuring.XReference);
                Points points = new Points();

                // 一毫米的点数
                int M1count = (int)(1f / this.m_Measuring.XInterval);

                // 收集测量数据
                for (int i = 0; i < (listMeasureData.Count - 1); i++)
                {
                    points.Add(listMeasureData.Points[i]);
                }

                this.m_KeyX = new List<float>();

                // 查找关键点
                for (int i = 0; i < listSdtKey.Count; i++)
                {
                    if (i == 0)
                    {
                        // 查找第一个关键点
                        this.m_KeyX.Add(0f);
                    }
                    else if (i == (listSdtKey.Count - 1))
                    {
                        // 查找最后一个关键点
                        this.m_KeyX.Add(Measuring.Size.Width);
                    }
                    else
                    {
                        float LeftIndx, RightIndex;
                        Points points2 = new Points();

                        if (listSdtKey[i].Point.X < 0f)
                        {
                            // 参考线左边的点
                            LeftIndx = listSdtKey[i].Point.X - 5;
                            RightIndex = 5 + listSdtKey[i].Point.X;

                            // 在测量数据中查找范围内的点
                            for (int j = 0; j < points.Count; j++)
                            {
                                PointF tf = points[j];
                                if (tf.X > LeftIndx && tf.X < RightIndex)
                                {
                                    points2.Add(tf);
                                }
                            }

                            if (points2.Count > M1count)
                            {
                                this.m_KeyX.Add(Measuring.XReference + this.XLocation(points2, M1count, listSdtKey[i].Point.X));
                            }
                        }
                        else if (listSdtKey[i].Point.X == 0f)
                        {
                            // 中心点
                            this.m_KeyX.Add(Measuring.XReference);
                        }
                        else
                        {
                            // 参考线右边的点
                            LeftIndx = listSdtKey[i].Point.X - 5;
                            RightIndex = 5 + listSdtKey[i].Point.X;

                            for (int j = 0; j < points.Count; j++)
                            {
                                PointF tf = points[(points.Count - 1) - j];
                                if (tf.X > LeftIndx && tf.X < RightIndex)
                                {
                                    points2.Add(tf);
                                }
                            }

                            if (points2.Count > M1count)
                            {
                                this.m_KeyX.Add(Measuring.XReference + this.XLocation(points2, M1count, listSdtKey[i].Point.X));
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 根据给定的测量点数据和名义X值，计算关键点的X轴位置。
        /// </summary>
        /// <param name="Points">测量点列表。</param>
        /// <param name="M1count">每毫米点数。</param>
        /// <param name="NominalX">名义X值。</param>
        /// <returns>计算出的X轴位置。</returns>
        private float XLocation(Points Points, int M1count, float NominalX)
        {
            float Min = 360;
            float retX = NominalX;
            float Angle1;

            int num = Points.Count - M1count * 3 - 1;
            for (int i = M1count * 3; i < num; i++)
            {
                Angle1 = Convert.ToSingle(Angle.GetAngle(Points[i], Points[i - M1count * 3], Points[i + M1count * 3]));

                if (Angle1 < Min)
                {
                    Min = Angle1;
                    retX = Points[i].X;
                }
            }

            return retX;
        }

        /// <summary>
        /// 获取计算后的关键点X轴位置列表。
        /// </summary>
        public List<float> KeyX
        {
            get
            {
                return this.m_KeyX;
            }
        }
    }

}
